#include "lcd.h"
#include "drv_timer.h"

#define lcd_spi_send_byte	spi_byte_write

//static void st7789_init(void);
static void st7735_init(void);

/**
  * @brief st7789v Initialization Function
  * @param None
  * @retval None
  */
void lcd_init(void)
{  
	gpio_init_type gpio_initstructure;
	crm_periph_clock_enable(LCD_DC_GPIO_CRM_CLK, TRUE);
	crm_periph_clock_enable(LCD_CS_GPIO_CRM_CLK, TRUE);
	crm_periph_clock_enable(LCD_BL_GPIO_CRM_CLK, TRUE);
	crm_periph_clock_enable(LCD_RST_GPIO_CRM_CLK, TRUE);
	crm_periph_clock_enable(LCD_SCK_GPIO_CRM_CLK, TRUE);
	crm_periph_clock_enable(LCD_MOSI_GPIO_CRM_CLK, TRUE);

	gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
	gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;
	gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
	gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
	gpio_initstructure.gpio_pins           = LCD_DC_PIN;
	gpio_init(LCD_DC_GPIO, &gpio_initstructure);
	LCD_DC_H;
	gpio_initstructure.gpio_pins           = LCD_CS_PIN;
	gpio_init(LCD_CS_GPIO, &gpio_initstructure);
	LCD_CS_H;
	gpio_initstructure.gpio_pins           = LCD_RST_PIN;
	gpio_init(LCD_RST_GPIO, &gpio_initstructure);
	LCD_RST_H;	
	gpio_initstructure.gpio_pins           = LCD_SCK_PIN;
	gpio_init(LCD_RST_GPIO, &gpio_initstructure);
	LCD_SCK_H;	
	gpio_initstructure.gpio_pins           = LCD_MOSI_PIN;
	gpio_init(LCD_MOSI_GPIO, &gpio_initstructure);
	LCD_MOSI_H;	

	gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
	gpio_initstructure.gpio_pins           = LCD_BL_PIN;
	gpio_init(LCD_BL_GPIO, &gpio_initstructure);
	LCD_BL_ON;

	spi1_init();

	st7735_init();
	
	timer3_oc_int();
}


void lcd_back_light_set(u8 val)
{
	u32 temp_val = 0;
	
	if(val > LCD_BACK_LIGHT_MAX)
		val = LCD_BACK_LIGHT_MAX;
	//val = 0 表示关闭背光
	//val(1-100)表示背光的25%-100%
	//背光亮度值计算方法：首先CTRL_PWM_CYCLE-CTRL_PWM_CYCLE/4 计算背光90%的占空比数值，并将这90%的占空比数值均分100份，然后乘val，最后再加上10%基础背光的占空比数值
	
	if(val == 0)
	{
		temp_val = 0;
	}
	else
	{
		temp_val = (u32)(LCD_PWM_CYCLE - LCD_PWM_MIN) * val / LCD_BACK_LIGHT_MAX + LCD_PWM_MIN;
	}
	set_timer3_oc_val(temp_val, 3);
}

#if 0
static void st7789_init(void)
{
	LCD_RST_L;
	delay_ms(20);
	LCD_RST_H;

	lcd_write_cmd(0x01);
	delay_ms(20);
	lcd_write_cmd(0x36); 
	lcd_write_data(0x60);
	
	lcd_write_cmd(0x3A); 
	lcd_write_data(0x05);

	lcd_write_cmd(0xB2);
	lcd_write_data(0x0C);
	lcd_write_data(0x0C);
	lcd_write_data(0x00);
	lcd_write_data(0x33);
	lcd_write_data(0x33);

	lcd_write_cmd(0xB7); 
	lcd_write_data(0x35);  

	lcd_write_cmd(0xBB);
	lcd_write_data(0x19);

	lcd_write_cmd(0xC0);
	lcd_write_data(0x2C);

	lcd_write_cmd(0xC2);
	lcd_write_data(0x01);

	lcd_write_cmd(0xC3);
	lcd_write_data(0x12);   

	lcd_write_cmd(0xC4);
	lcd_write_data(0x20);  

	lcd_write_cmd(0xC6); 
	lcd_write_data(0x0F);    

	lcd_write_cmd(0xD0); 
	lcd_write_data(0xA4);
	lcd_write_data(0xA1);

	lcd_write_cmd(0xE0);
	lcd_write_data(0xD0);
	lcd_write_data(0x04);
	lcd_write_data(0x0D);
	lcd_write_data(0x11);
	lcd_write_data(0x13);
	lcd_write_data(0x2B);
	lcd_write_data(0x3F);
	lcd_write_data(0x54);
	lcd_write_data(0x4C);
	lcd_write_data(0x18);
	lcd_write_data(0x0D);
	lcd_write_data(0x0B);
	lcd_write_data(0x1F);
	lcd_write_data(0x23);

	lcd_write_cmd(0xE1);
	lcd_write_data(0xD0);
	lcd_write_data(0x04);
	lcd_write_data(0x0C);
	lcd_write_data(0x11);
	lcd_write_data(0x13);
	lcd_write_data(0x2C);
	lcd_write_data(0x3F);
	lcd_write_data(0x44);
	lcd_write_data(0x51);
	lcd_write_data(0x2F);
	lcd_write_data(0x1F);
	lcd_write_data(0x1F);
	lcd_write_data(0x20);
	lcd_write_data(0x23);

	lcd_write_cmd(0x21); 

	lcd_write_cmd(0x11); 
	delay_ms(20); 

	lcd_write_cmd(0x29); 	
}
#endif
static void st7735_init(void)
{
    LCD_SCK_L;	
    LCD_RST_L;
    delay_ms(200);	
    LCD_RST_H;	
    delay_ms(200);

	lcd_write_cmd(0x11);       //Sleep Out
	delay_ms(120);   

	lcd_write_cmd(0x36); 		//Memory Data Access Control
	lcd_write_data(0xC0); 			//Y£¬X·´ת£¬RGBģʽ
	  
	lcd_write_cmd(0xB1);     //------------------------------------ST7735S Frame Rate-----------------------------------------//
	lcd_write_data(0x05);   
	lcd_write_data(0x3C);   
	lcd_write_data(0x3C);   

	lcd_write_cmd(0xB2);     
	lcd_write_data(0x05);   
	lcd_write_data(0x3C);   
	lcd_write_data(0x3C);   

	lcd_write_cmd(0xB3);     
	lcd_write_data(0x05);   
	lcd_write_data(0x3C);   
	lcd_write_data(0x3C);   
	lcd_write_data(0x05);   
	lcd_write_data(0x3C);   
	lcd_write_data(0x3C);   //------------------------------------End ST7735S Frame Rate-----------------------------------------//

	lcd_write_cmd(0xB4);     //Dot inversion
	lcd_write_data(0x03);   

	lcd_write_cmd(0xC0);     //------------------------------------ST7735S Power Sequence-----------------------------------------//
	lcd_write_data(0x0E);   
	lcd_write_data(0x0E);   
	lcd_write_data(0x04);   

	lcd_write_cmd(0xC1);     
	lcd_write_data(0xC0);   

	lcd_write_cmd(0xC2);     
	lcd_write_data(0x0D);   
	lcd_write_data(0x00);   

	lcd_write_cmd(0xC3);     
	lcd_write_data(0x8D);   
	lcd_write_data(0x2A);   

	lcd_write_cmd(0xC4);     
	lcd_write_data(0x8D);   
	lcd_write_data(0xEE);   //---------------------------------End ST7735S Power Sequence-------------------------------------//

	lcd_write_cmd(0xC5);     //VCOM
	lcd_write_data(0x04);   

	lcd_write_cmd(0x36);     //MX, MY, RGB mode
	lcd_write_data(0x78);
	lcd_write_cmd(0x3a);  
	lcd_write_data(0x05);  

	lcd_write_cmd(0xE0);     
	lcd_write_data(0x05);   
	lcd_write_data(0x1A);   
	lcd_write_data(0x0B);   
	lcd_write_data(0x15);   
	lcd_write_data(0x3D);   
	lcd_write_data(0x38);   
	lcd_write_data(0x2E);   
	lcd_write_data(0x30);   
	lcd_write_data(0x2D);   
	lcd_write_data(0x28);   
	lcd_write_data(0x30);   
	lcd_write_data(0x3B);   
	lcd_write_data(0x00);   
	lcd_write_data(0x01);   
	lcd_write_data(0x02);   
	lcd_write_data(0x10);   

	lcd_write_cmd(0xE1);     
	lcd_write_data(0x05);   
	lcd_write_data(0x1A);   
	lcd_write_data(0x0B);   
	lcd_write_data(0x15);   
	lcd_write_data(0x36);   
	lcd_write_data(0x2E);   
	lcd_write_data(0x28);   
	lcd_write_data(0x2B);   
	lcd_write_data(0x2B);   
	lcd_write_data(0x28);   
	lcd_write_data(0x30);   
	lcd_write_data(0x3B);   
	lcd_write_data(0x00);   
	lcd_write_data(0x01);   
	lcd_write_data(0x02);   
	lcd_write_data(0x10);  

	lcd_write_cmd(0x20); //
	lcd_write_cmd(0x11); //Sleep out
	delay_ms (100); //Delay 120ms
	lcd_write_cmd(0x29); 
}

#ifdef USE_HW_SPI
void lcd_write_cmd(u8 o_command)
{
	LCD_DC_L;
	
	LCD_CS_L;
	lcd_spi_send_byte(o_command);
	
	LCD_CS_H;
}
void lcd_write_data(u8 o_data)
{
	LCD_DC_H;
	LCD_CS_L;
	
	lcd_spi_send_byte(o_data);
	
	LCD_CS_H;	
}
void lcd_write_halfword(u16 o_data)
{
    u8 data[2] = {0};

    data[0] = o_data >> 8;
    data[1] = (u8)o_data;

	LCD_DC_H;
	LCD_CS_L;
	
	lcd_spi_send_byte(data[0]);
	lcd_spi_send_byte(data[1]);
	
	LCD_CS_H;
}
void lcd_write_n_data(u8 *o_data, u16 n)
{
    u16 j = 0;
	LCD_DC_H;
	LCD_CS_L;

	for(j=0; j<n; j++)
	{
		lcd_spi_send_byte(o_data[j]);
	}
	LCD_CS_H;
}


#else

	#ifdef USE_SF_SPI
void lcd_spi_send_byte(u8 byte)				//向液晶屏写一个8位数据
{
	u16 counter;
	LCD_CS_L;

	for(counter=0;counter<8;counter++)
	{
		LCD_SCK_L;	  
		if((byte&0x80)==0)
			LCD_MOSI_L;
		else 
			LCD_MOSI_H;
//		delay_us(1);
		byte=byte<<1;	
		LCD_SCK_H;
//		delay_us(1);
	}
  
	LCD_SCK_L;
}


void lcd_write_cmd(u8 o_command)
{
	LCD_DC_L;
	LCD_CS_L;
	lcd_spi_send_byte(o_command);
	LCD_CS_H;

	//LCD_DC_H;
}
//向液晶屏写一个8位数据
void lcd_write_data(u8 o_data)
{ 
	LCD_DC_H;
	LCD_CS_L;
	
	lcd_spi_send_byte(o_data);
	
	LCD_CS_H;
}
void lcd_write_halfword(u16 o_data)
{
    u16 data[2] = {0};

    data[0] = o_data >> 8;
    data[1] = o_data;

	LCD_DC_H;
	LCD_CS_L;
	
	lcd_spi_send_byte(data[0]);
	lcd_spi_send_byte(data[1]);
	
	LCD_CS_H;		
}
void lcd_write_n_data(u8 *o_data, u16 n)
{
    u16 j = 0;
	LCD_DC_H;
	LCD_CS_L;

	for(j=0; j<n; j++)
	{
		lcd_spi_send_byte(o_data[j]);
	}
	LCD_CS_H;
}
	#endif
#endif

//(160,0)  == (0,0)
//(160,80) == (80,0)
void lcd_set_address(u16 x1, u16 y1, u16 x2, u16 y2)
{
//	u16 temp = 0;
//	temp = x1;
//	x1 = y1;	y1 = 160 - temp - 1;
//	temp = x2;
//	x2 = y2;	y2 = 160 - temp - 1;
//		
//////可用，配合C8
//	lcd_write_cmd(0x2A);     //窗口地址横向                   
//	lcd_write_data(x1>>8);     
//	lcd_write_data(x1+24);//start column
//	lcd_write_data(x2>>8);     
//	lcd_write_data(x2+24);//start column
//	lcd_write_cmd(0x2B);     //窗口地址纵向                   
//	lcd_write_data(y1>>8);     
//	lcd_write_data(y1);		//start row
//	lcd_write_data(y2>>8);     
//	lcd_write_data(y2);		//start row
//	lcd_write_cmd(0x2C);     //写入数据  


	lcd_write_cmd(0x2A);     //窗口地址横向                   
	lcd_write_data(x1>>8);     
	lcd_write_data(x1+0);//start column
	lcd_write_data(x2>>8);     
	lcd_write_data(x2+0);//start column
	lcd_write_cmd(0x2B);     //窗口地址纵向                   
	lcd_write_data(y1>>8);     
	lcd_write_data(y1+24);		//start row
	lcd_write_data(y2>>8);     
	lcd_write_data(y2+24);		//start row
	lcd_write_cmd(0x2C);     //写入数据   
}


void lcd_full(u16 color)
{
	u16 ROW,column;

	lcd_set_address(0, 0, LCD_X_MAX-1, LCD_Y_MAX-1);
	for(ROW=0; ROW<LCD_Y_MAX; ROW++)             
	{
		for(column=0; column<LCD_X_MAX ;column++) 
		{
			lcd_write_halfword(color);
		}
	}
}

void lcd_draw_point(u16 x, u16 y, u16 color)
{
	lcd_set_address(x, y, x, y);
	lcd_write_halfword(color);
}


extern void LCD_Fill(u16 x_start, u16 y_start, u16 x_end, u16 y_end, u16 color);
void lcd_clear(u16 color)
{
#if 1	
	lcd_full(color);
#else	
	LCD_Fill(0, 0, LCD_X_MAX-1, LCD_Y_MAX-1, color);
#endif
}




void lcd_write_ndata_16bit_increment(uint16_t *wdata, uint32_t len)
{
    u8 data[2] = {0};

    u16 j = 0;
	LCD_DC_H;
	LCD_CS_L;

	for(j=0; j<len; j++)
	{
		data[0] = wdata[j] >> 8;
		data[1] = (u8)wdata[j];
		
		lcd_spi_send_byte(data[0]);
		lcd_spi_send_byte(data[1]);
	}	
	LCD_CS_H;
}


void lcd_fill_diff_color(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t *array)
{
	uint32_t len = (x2-x1+1)*(y2-y1+1);
	lcd_set_address(x1, y1, x2, y2);
	lcd_write_ndata_16bit_increment(array,len);
}

 


